
<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<style>
			body {
				background: black;
				color: rgb(80, 80, 80);
			}
			body, pre, #legend span {
				font-family: Menlo, monospace;
				font-weight: bold;
			}
			#topbar {
				background: black;
				position: fixed;
				top: 0; left: 0; right: 0;
				height: 42px;
				border-bottom: 1px solid rgb(80, 80, 80);
			}
			#content {
				margin-top: 50px;
			}
			#nav, #legend {
				float: left;
				margin-left: 10px;
			}
			#legend {
				margin-top: 12px;
			}
			#nav {
				margin-top: 10px;
			}
			#legend span {
				margin: 0 5px;
			}
			.cov0 { color: rgb(192, 0, 0) }
.cov1 { color: rgb(128, 128, 128) }
.cov2 { color: rgb(116, 140, 131) }
.cov3 { color: rgb(104, 152, 134) }
.cov4 { color: rgb(92, 164, 137) }
.cov5 { color: rgb(80, 176, 140) }
.cov6 { color: rgb(68, 188, 143) }
.cov7 { color: rgb(56, 200, 146) }
.cov8 { color: rgb(44, 212, 149) }
.cov9 { color: rgb(32, 224, 152) }
.cov10 { color: rgb(20, 236, 155) }

		</style>
	</head>
	<body>
		<div id="topbar">
			<div id="nav">
				<select id="files">
				
				<option value="file0">github.com/warthog618/gpiod/uapi/uapi.go (98.9%)</option>
				
				</select>
			</div>
			<div id="legend">
				<span>not tracked</span>
			
				<span class="cov0">not covered</span>
				<span class="cov8">covered</span>
			
			</div>
		</div>
		<div id="content">
		
		<pre class="file" id="file0" style="display: none">// SPDX-License-Identifier: MIT
//
// Copyright © 2019 Kent Gibson &lt;warthog618@gmail.com&gt;.

// +build linux

// Package uapi provides the Linux GPIO UAPI definitions for gpiod.
package uapi

import (
        "bytes"
        "encoding/binary"
        "unsafe"

        "golang.org/x/sys/unix"
)

// GetChipInfo returns the ChipInfo for the GPIO character device.
//
// The fd is an open GPIO character device.
func GetChipInfo(fd uintptr) (ChipInfo, error) <span class="cov8" title="1">{
        var ci ChipInfo
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(getChipInfoIoctl),
                uintptr(unsafe.Pointer(&amp;ci)))
        if errno != 0 </span><span class="cov8" title="1">{
                return ci, errno
        }</span>
        <span class="cov8" title="1">return ci, nil</span>
}

// GetLineInfo returns the LineInfo for one line from the GPIO character device.
//
// The fd is an open GPIO character device.
// The offset is zero based.
func GetLineInfo(fd uintptr, offset int) (LineInfo, error) <span class="cov8" title="1">{
        var li LineInfo
        li.Offset = uint32(offset)
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(getLineInfoIoctl),
                uintptr(unsafe.Pointer(&amp;li)))
        if errno != 0 </span><span class="cov8" title="1">{
                return LineInfo{}, errno
        }</span>
        <span class="cov8" title="1">return li, nil</span>
}

// GetLineEvent requests a line from the GPIO character device with event
// reporting enabled.
//
// The fd is an open GPIO character device.
// The line must be an input and must not already be requested.
// If successful, the fd for the line is returned in the request.fd.
func GetLineEvent(fd uintptr, request *EventRequest) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(getLineEventIoctl),
                uintptr(unsafe.Pointer(request)))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// GetLineHandle requests a line from the GPIO character device.
//
// This request is without event reporting.
// The fd is an open GPIO character device.
// The lines must not already be requested.
// The flags in the request will be applied to all lines in the request.
// If successful, the fd for the line is returned in the request.fd.
func GetLineHandle(fd uintptr, request *HandleRequest) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(getLineHandleIoctl),
                uintptr(unsafe.Pointer(request)))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// GetLineValues returns the values of a set of requested lines.
//
// The fd is a requested line, as returned by GetLineHandle or GetLineEvent.
func GetLineValues(fd uintptr, values *HandleData) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(getLineValuesIoctl),
                uintptr(unsafe.Pointer(&amp;values[0])))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// SetLineValues sets the values of a set of requested lines.
//
// The fd is a requested line, as returned by GetLineHandle or GetLineEvent.
func SetLineValues(fd uintptr, values HandleData) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(setLineValuesIoctl),
                uintptr(unsafe.Pointer(&amp;values[0])))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// SetLineConfig sets the config of an existing handle request.
//
// The config flags in the request will be applied to all lines in the handle
// request.
func SetLineConfig(fd uintptr, config *HandleConfig) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(setLineConfigIoctl),
                uintptr(unsafe.Pointer(config)))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// WatchLineInfo sets a watch on info of a line.
//
// A watch is set on the line indicated by info.Offset. If successful the
// current line info is returned, else an error is returned.
func WatchLineInfo(fd uintptr, info *LineInfo) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(watchLineInfoIoctl),
                uintptr(unsafe.Pointer(info)))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// UnwatchLineInfo clears a watch on info of a line.
//
// Disables the watch on info for the line.
func UnwatchLineInfo(fd uintptr, offset uint32) error <span class="cov8" title="1">{
        _, _, errno := unix.Syscall(unix.SYS_IOCTL,
                fd,
                uintptr(unwatchLineInfoIoctl),
                uintptr(unsafe.Pointer(&amp;offset)))
        if errno != 0 </span><span class="cov8" title="1">{
                return errno
        }</span>
        <span class="cov8" title="1">return nil</span>
}

// BytesToString is a helper function that converts strings stored in byte
// arrays, as returned by GetChipInfo and GetLineInfo, into strings.
func BytesToString(a []byte) string <span class="cov8" title="1">{
        n := bytes.IndexByte(a, 0)
        if n == -1 </span><span class="cov8" title="1">{
                return string(a)
        }</span>
        <span class="cov8" title="1">return string(a[:n])</span>
}

type fdReader int

func (fd fdReader) Read(b []byte) (int, error) <span class="cov8" title="1">{
        return unix.Read(int(fd), b[:])
}</span>

// ReadEvent reads a single event from a requested line.
//
// The fd is a requested line, as returned by GetLineEvent.
//
// This function is blocking and should only be called when the fd is known to
// be ready to read.
func ReadEvent(fd uintptr) (EventData, error) <span class="cov8" title="1">{
        var ed EventData
        err := binary.Read(fdReader(fd), nativeEndian, &amp;ed)
        return ed, err
}</span>

// ReadLineInfoChanged reads a line info changed event from a chip.
//
// The fd is an open GPIO character device.
//
// This function is blocking and should only be called when the fd is known to
// be ready to read.
func ReadLineInfoChanged(fd uintptr) (LineInfoChanged, error) <span class="cov8" title="1">{
        var lic LineInfoChanged
        err := binary.Read(fdReader(fd), nativeEndian, &amp;lic)
        return lic, err
}</span>

// IOCTL command codes
type ioctl uintptr

var (
        getChipInfoIoctl     ioctl
        getLineInfoIoctl     ioctl
        getLineHandleIoctl   ioctl
        getLineEventIoctl    ioctl
        getLineValuesIoctl   ioctl
        setLineValuesIoctl   ioctl
        setLineConfigIoctl   ioctl
        watchLineInfoIoctl   ioctl
        unwatchLineInfoIoctl ioctl
)

// Size of name and consumer strings.
const nameSize = 32

func init() <span class="cov8" title="1">{
        // ioctls require struct sizes which are only available at runtime.
        var ci ChipInfo
        getChipInfoIoctl = ior(0xB4, 0x01, unsafe.Sizeof(ci))
        var li LineInfo
        getLineInfoIoctl = iorw(0xB4, 0x02, unsafe.Sizeof(li))
        var hr HandleRequest
        getLineHandleIoctl = iorw(0xB4, 0x03, unsafe.Sizeof(hr))
        var le EventRequest
        getLineEventIoctl = iorw(0xB4, 0x04, unsafe.Sizeof(le))
        var hd HandleData
        getLineValuesIoctl = iorw(0xB4, 0x08, unsafe.Sizeof(hd))
        setLineValuesIoctl = iorw(0xB4, 0x09, unsafe.Sizeof(hd))
        var hc HandleConfig
        setLineConfigIoctl = iorw(0xB4, 0x0a, unsafe.Sizeof(hc))
        watchLineInfoIoctl = iorw(0xB4, 0x0b, unsafe.Sizeof(li))
        unwatchLineInfoIoctl = iorw(0xB4, 0x0c, unsafe.Sizeof(li.Offset))
}</span>

// ChipInfo contains the details of a GPIO chip.
type ChipInfo struct {
        // The system name of the device.
        Name [nameSize]byte

        // An identifying label added by the device driver.
        Label [nameSize]byte

        // The number of lines supported by this chip.
        Lines uint32
}

// LineInfo contains the details of a single line of a GPIO chip.
type LineInfo struct {
        // The offset of the line within the chip.
        Offset uint32

        // The line flags applied to this line.
        Flags LineFlag

        // The system name for this line.
        Name [nameSize]byte

        // If requested, a string added by the requester to identify the
        // owner of the request.
        Consumer [nameSize]byte
}

// LineInfoChanged contains the details of a change to line info.
//
// This is returned via the chip fd in response to changes to watched lines.
type LineInfoChanged struct {
        // The updated info.
        Info LineInfo

        // The time the change occured.
        Timestamp uint64

        // The type of change.
        Type ChangeType

        // reserved for future use.
        _ [5]uint32
}

// ChangeType indicates the type of change that has occured to a line.
type ChangeType uint32

const (
        _ ChangeType = iota

        // LineChangedRequested indicates the line has been requested.
        LineChangedRequested

        // LineChangedReleased indicates the line has been released.
        LineChangedReleased

        // LineChangedConfig indicates the line configuration has changed.
        LineChangedConfig
)

// LineFlag are the flags for a line.
type LineFlag uint32

const (
        // LineFlagRequested indicates that the line has been requested.
        // It may have been requested by this process or another process.
        // The line cannot be requested again until this flag is clear.
        LineFlagRequested LineFlag = 1 &lt;&lt; iota

        // LineFlagIsOut indicates that the line is an output.
        LineFlagIsOut

        // LineFlagActiveLow indicates that the line is active low.
        LineFlagActiveLow

        // LineFlagOpenDrain indicates that the line will pull low when set low but
        // float when set high. This flag only applies to output lines.
        // An output cannot be both open drain and open source.
        LineFlagOpenDrain

        // LineFlagOpenSource indicates that the line will pull high when set high
        // but float when set low. This flag only applies to output lines.
        // An output cannot be both open drain and open source.
        LineFlagOpenSource

        // LineFlagPullUp indicates that the internal line pull up is enabled.
        LineFlagPullUp

        // LineFlagPullDown indicates that the internal line pull down is enabled.
        LineFlagPullDown

        // LineFlagBiasDisable indicates that the internal line bias is disabled.
        LineFlagBiasDisable
)

// IsRequested returns true if the line is requested.
func (f LineFlag) IsRequested() bool <span class="cov8" title="1">{
        return f&amp;LineFlagRequested != 0
}</span>

// IsOut returns true if the line is an output.
func (f LineFlag) IsOut() bool <span class="cov8" title="1">{
        return f&amp;LineFlagIsOut != 0
}</span>

// IsActiveLow returns true if the line is active low.
func (f LineFlag) IsActiveLow() bool <span class="cov8" title="1">{
        return f&amp;LineFlagActiveLow != 0
}</span>

// IsOpenDrain returns true if the line is open-drain.
func (f LineFlag) IsOpenDrain() bool <span class="cov8" title="1">{
        return f&amp;LineFlagOpenDrain != 0
}</span>

// IsOpenSource returns true if the line is open-source.
func (f LineFlag) IsOpenSource() bool <span class="cov8" title="1">{
        return f&amp;LineFlagOpenSource != 0
}</span>

// IsBiasDisable returns true if the line has bias disabled.
func (f LineFlag) IsBiasDisable() bool <span class="cov8" title="1">{
        return f&amp;LineFlagBiasDisable != 0
}</span>

// IsPullDown returns true if the line has pull-down enabled.
func (f LineFlag) IsPullDown() bool <span class="cov8" title="1">{
        return f&amp;LineFlagPullDown != 0
}</span>

// IsPullUp returns true if the line has pull-up enabled.
func (f LineFlag) IsPullUp() bool <span class="cov8" title="1">{
        return f&amp;LineFlagPullUp != 0
}</span>

// HandleConfig is a request to change the config of an existing request.
//
// Can be applied to both handle and event requests.
// Event requests cannot be reconfigured to outputs.
type HandleConfig struct {
        // The flags to be applied to the lines.
        Flags HandleFlag

        // The default values to be applied to output lines (when
        // HandleRequestOutput is set in the Flags).
        DefaultValues [HandlesMax]uint8

        // reserved for future use.
        _ [4]uint32
}

// HandleRequest is a request for control of a set of lines.
// The lines must all be on the same GPIO chip.
type HandleRequest struct {
        // The lines to be requested.
        Offsets [HandlesMax]uint32

        // The flags to be applied to the lines.
        Flags HandleFlag

        // The default values to be applied to output lines.
        DefaultValues [HandlesMax]uint8

        // The string identifying the requester to be applied to the lines.
        Consumer [nameSize]byte

        // The number of lines being requested.
        Lines uint32

        // The file handle for the requested lines.
        // Set if the request is successful.
        Fd int32
}

// HandleFlag contains the
type HandleFlag uint32

const (
        // HandleRequestInput requests the line as an input.
        //
        // This is ignored if Output is also set.
        HandleRequestInput HandleFlag = 1 &lt;&lt; iota

        // HandleRequestOutput requests the line as an output.
        //
        // This takes precedence over Input, if both are set.
        HandleRequestOutput

        // HandleRequestActiveLow requests the line be made active low.
        HandleRequestActiveLow

        // HandleRequestOpenDrain requests the line be made open drain.
        //
        // This option requires the line to be requested as an Output.
        // This cannot be set at the same time as OpenSource.
        HandleRequestOpenDrain

        // HandleRequestOpenSource requests the line be made open source.
        //
        // This option requires the line to be requested as an Output.
        // This cannot be set at the same time as OpenDrain.
        HandleRequestOpenSource

        // HandleRequestPullUp requests the line have pull-up enabled.
        HandleRequestPullUp

        // HandleRequestPullDown requests the line have pull-down enabled.
        HandleRequestPullDown

        // HandleRequestBiasDisable requests the line have bias disabled.
        HandleRequestBiasDisable

        // HandlesMax is the maximum number of lines that can be requested in a
        // single request.
        HandlesMax = 64
)

// IsInput returns true if the line is requested as an input.
func (f HandleFlag) IsInput() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestInput != 0
}</span>

// IsOutput returns true if the line is requested as an output.
func (f HandleFlag) IsOutput() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestOutput != 0
}</span>

// IsActiveLow returns true if the line is requested as a active low.
func (f HandleFlag) IsActiveLow() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestActiveLow != 0
}</span>

// IsOpenDrain returns true if the line is requested as an open drain.
func (f HandleFlag) IsOpenDrain() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestOpenDrain != 0
}</span>

// IsOpenSource returns true if the line is requested as an open source.
func (f HandleFlag) IsOpenSource() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestOpenSource != 0
}</span>

// IsBiasDisable returns true if the line is requested with bias disabled.
func (f HandleFlag) IsBiasDisable() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestBiasDisable != 0
}</span>

// IsPullDown returns true if the line is requested with pull-down enabled.
func (f HandleFlag) IsPullDown() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestPullDown != 0
}</span>

// IsPullUp returns true if the line is requested with pull-up enabled.
func (f HandleFlag) IsPullUp() bool <span class="cov8" title="1">{
        return f&amp;HandleRequestPullUp != 0
}</span>

// HandleData contains the logical value for each line.
// Zero is a logical low and any other value is a logical high.
type HandleData [HandlesMax]uint8

// EventRequest is a request for control of a line with event reporting enabled.
type EventRequest struct {
        // The line to be requested.
        Offset uint32

        // The line flags applied to this line.
        HandleFlags HandleFlag

        // The type of events to report.
        EventFlags EventFlag

        // The string identifying the requester to be applied to the line.
        Consumer [nameSize]byte

        // The file handle for the requested line.
        // Set if the request is successful.
        Fd int32
}

// EventFlag indicates the types of events that will be reported.
type EventFlag uint32

const (
        // EventRequestRisingEdge requests rising edge events.
        // This means a transition from a low logical state to a high logical state.
        // For active high lines (the default) this means a transition from a
        // physical low to a physical high.
        // Note that for active low lines this means a transition from a physical
        // high to a physical low.
        EventRequestRisingEdge EventFlag = 1 &lt;&lt; iota

        // EventRequestFallingEdge requests falling edge events.
        // This means a transition from a high logical state to a low logical state.
        // For active high lines (the default) this means a transition from a
        // physical high to a physical low.
        // Note that for active low lines this means a transition from a physical
        // low to a physical high.
        EventRequestFallingEdge

        // EventRequestBothEdges requests both rising and falling edge events.
        // This is equivalent to requesting both EventRequestRisingEdge and
        // EventRequestRisingEdge.
        EventRequestBothEdges = EventRequestRisingEdge | EventRequestFallingEdge
)

// IsRisingEdge returns true if rising edge events have been requested.
func (f EventFlag) IsRisingEdge() bool <span class="cov8" title="1">{
        return f&amp;EventRequestRisingEdge != 0
}</span>

// IsFallingEdge returns true if falling edge events have been requested.
func (f EventFlag) IsFallingEdge() bool <span class="cov8" title="1">{
        return f&amp;EventRequestFallingEdge != 0
}</span>

// IsBothEdges returns true if both rising and falling edge events have been
// requested.
func (f EventFlag) IsBothEdges() bool <span class="cov8" title="1">{
        return f&amp;EventRequestBothEdges == EventRequestBothEdges
}</span>

// EventData contains the details of a particular line event.
//
// This is returned via the event request fd in response to events.
type EventData struct {
        // The time the event was detected.
        Timestamp uint64

        // The type of event detected.
        ID uint32

        // pad to workaround 64bit OS padding
        _ uint32
}

// ioctl constants
const (
        iocNRBits    = 8
        iocTypeBits  = 8
        iocDirBits   = 2
        iocSizeBits  = 14
        iocNRShift   = 0
        iocTypeShift = iocNRShift + iocNRBits
        iocSizeShift = iocTypeShift + iocTypeBits
        iocDirShift  = iocSizeShift + iocSizeBits
        iocWrite     = 1
        iocRead      = 2
)

func ior(t, nr, size uintptr) ioctl <span class="cov8" title="1">{
        return ioctl((iocRead &lt;&lt; iocDirShift) |
                (size &lt;&lt; iocSizeShift) |
                (t &lt;&lt; iocTypeShift) |
                (nr &lt;&lt; iocNRShift))
}</span>

func iorw(t, nr, size uintptr) ioctl <span class="cov8" title="1">{
        return ioctl(((iocRead | iocWrite) &lt;&lt; iocDirShift) |
                (size &lt;&lt; iocSizeShift) |
                (t &lt;&lt; iocTypeShift) |
                (nr &lt;&lt; iocNRShift))
}</span>

func iow(t, nr, size uintptr) ioctl <span class="cov0" title="0">{
        return ioctl((iocWrite &lt;&lt; iocDirShift) |
                (size &lt;&lt; iocSizeShift) |
                (t &lt;&lt; iocTypeShift) |
                (nr &lt;&lt; iocNRShift))
}</span>
</pre>
		
		</div>
	</body>
	<script>
	(function() {
		var files = document.getElementById('files');
		var visible;
		files.addEventListener('change', onChange, false);
		function select(part) {
			if (visible)
				visible.style.display = 'none';
			visible = document.getElementById(part);
			if (!visible)
				return;
			files.value = part;
			visible.style.display = 'block';
			location.hash = part;
		}
		function onChange() {
			select(files.value);
			window.scrollTo(0, 0);
		}
		if (location.hash != "") {
			select(location.hash.substr(1));
		}
		if (!visible) {
			select("file0");
		}
	})();
	</script>
</html>
